package com.sea.base.json.typeAdapter

import com.google.gson.Gson
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import java.io.StringReader

/**
 * 如果json是String内容是[...]，这里支持直接使用List、Set进行接收
 * 注意：如果String非空并且不是[]则依然会报错
 */
class StringCollectionTypeAdapterFactory : TypeAdapterFactory {

    override fun <T> create(gson: Gson, typeToken: TypeToken<T>): TypeAdapter<T>? {
        val rawType = typeToken.rawType
        if (!Collection::class.java.isAssignableFrom(rawType)) {
            return null
        }
        val delegateAdapter = gson.getDelegateAdapter(this, typeToken)
        @Suppress("UNCHECKED_CAST")
        return MyStringCollectionTypeAdapter(delegateAdapter as TypeAdapter<Collection<*>>) as TypeAdapter<T>
    }

    private class MyStringCollectionTypeAdapter<E>(
        private val delegateAdapter: TypeAdapter<Collection<E>>
    ) : TypeAdapter<Collection<E>>() {
        override fun write(out: JsonWriter, value: Collection<E>?) {
            delegateAdapter.write(out, value)
        }

        override fun read(`in`: JsonReader): Collection<E>? {
            if (`in`.peek() == JsonToken.STRING) {
                val st = `in`.nextString()
                if (st.isNullOrEmpty()) {
                    return null
                }
                return delegateAdapter.read(JsonReader(StringReader(st)))
            } else {
                return delegateAdapter.read(`in`)
            }
        }

    }
}